package com.zou.mall.auth.config;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.json.JSONUtil;
import com.zou.common.annotation.TokenCheck;
import com.zou.common.config.ClientInfoHolder;
import com.zou.common.utils.JwtUtil;
import com.zou.common.vo.UserVO;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Objects;

/**
 * @author leonard
 * @Description 接口访问拦截器
 * @date 2021-11-19 14:19
 */
@Slf4j
public class UserInterceptor implements HandlerInterceptor {

    @Autowired
    private JwtUtil jwtUtil;

    @Resource
    private RedisTemplate redisTemplate;

    /**
     * 访问控制器方法前执行
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        log.info(DateUtil.now() + "--preHandle:" + request.getRequestURL());

        if(true){
            return true;
        }


        TokenCheck annotation = null;
        if (handler instanceof HandlerMethod) {
            annotation = ((HandlerMethod) handler).getMethodAnnotation(TokenCheck.class);
        }

        // 如果有@TokenCheck 注解，并且check为true，检验token
        if (Objects.nonNull(annotation) && !annotation.check()) {
            return true;
        }

        //通过header的token鉴权判断即可
        String token = request.getHeader("token");
        if (validToken(token)) {
            Claims claims = jwtUtil.parseJWT(token);
            String username = MapUtil.getStr(claims, "username");
            String userStr = (String) redisTemplate.opsForValue().get("USER:" + username);
            if (StringUtils.isEmpty(username)) {
                return false;
            }
            UserVO user = JSONUtil.toBean(userStr, UserVO.class);
            ClientInfoHolder.setClientInfo(user);
            return true;
        }
        return false;
    }

    /**
     * 访问控制器方法后执行
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                           ModelAndView modelAndView) throws Exception {
        //log.info(new Date() + "--postHandle:" + request.getRequestURL());
    }

    /**
     * postHandle方法执行完成后执行，一般用于释放资源
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        //log.info(new Date() + "--afterCompletion:" + request.getRequestURL());
    }


    private boolean validToken(String token) {
        return StringUtils.isNotEmpty(token) && jwtUtil.checkedJWT(token);
    }
}
